package main

import "fmt"

func main() {
	// 什么是切片
	// 数组有一个很大的问题：大小确定，不能修改大小，==切片 -动态数组

	//var courses []string  // 定义了一个切片，不写长度
	//courses := []string{"django", "gin", "go"}
	var courses = []string{"django", "gin", "go"}
	fmt.Printf("%T\n", courses)

	// 切片另一种初始化方法 make
	// 切片不是没有长度限制吗，为什么make 初始化要传递长度，传递后是否长度像数组一样不可变
	courses2 := make([]string, 10)
	fmt.Printf("%T\n", courses2)
	fmt.Println(len(courses2))
	// slice 对标的就是Python 中的list

	// 第三种： 通过数组切片变成一个切片
	var courses3 = [5]string{"django", "gin", "beego", "flask", "tornado"}
	subCourse := courses3[1:4] // 切片 和 Python 中的是一样的 。 go 语言中的切片是一种数据结构

	//subCourse2 = courses3[-1:]  不能这样用 也不支持 1：4：2 间隔
	//python 中的切片非常灵活
	subCourse[0] = "lewen" // 切片修改值会影响原来数组的
	fmt.Println(courses3)
	fmt.Println(subCourse)
	fmt.Printf("subCourse type %T\n", subCourse) // 切片

	replace(subCourse)
	fmt.Println("replace subCourse func :", subCourse)

	// 第四种方法： new
	//subCourse5 := new([]string)
	//fmt.Println(subCourse5)

	// 数组的传递是值传递 切片是引用传递

	// === slice 是动态数组 需要动态添加值

	//fmt.Println(subCourse[1])

	subCourseA := subCourse[1:2]
	fmt.Printf("%T， %v\n", subCourseA, subCourseA)

	// append  可以向切片追加元素
	subCourseA = append(subCourseA, "imooc", "imooc2", "imooc3")
	fmt.Println("subCourseA", subCourseA)

	// copy
	//subCourseB := []string{}
	subCourseB := make([]string, 2)
	copy(subCourseB, subCourseA)
	fmt.Println(subCourseB)
	// 拷贝的时候目标长度需要设置好
	// 既然是切片为什么这个时候提出长度要求

	appendedCourse := []string{"shopee1", "shopee2"}
	subCourseB = append(subCourseB, appendedCourse...) // 函数的参数传递规则
	fmt.Println(subCourseB)

	// 切片中删除元素

	deleteCourse := [5]string{"shopee1", "shopee2", "shopee3", "shopee4", "shopee5"}
	deleteSlice := deleteCourse[:]
	deleteSlice = append(deleteCourse[:1], deleteCourse[2:]...) // 取巧的做法
	fmt.Println(deleteSlice)

	// 如何判断 某个元素是否在切片中 for 循环

	//python 和go 语言slice 区别 玩出花样
	// go 语言的底层是基于数组实现的
	// python 的list 也是基于数组实现的 C语言的数组 切片出来的是新的数组
	// slice 进行的操作都会影响原来的数组 slice更像是一个指针 本身不存值

}

func replace(myslice []string) {
	myslice[0] = "lewen"
}
